// *************************************************************************************************
//
// MK3D Engine
// --------------------------------------
// Copyright (C) 2007-2011 Zeb (mailto: zebbey@gmail.com)
//
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//
// *************************************************************************************************

#include "mk_header.h"
#include "mk_pack_zip.h"
#include "mk_engine.h"
#include "mk_log.h"

namespace MK3DE
{
	CPackZip::CPackZip()
	{

	}

	CPackZip::~CPackZip()
	{
		Destroy();
	}

	std::string CPackZip::__GetErrorDescription(zzip_error_t zzipError) 
	{
		std::string errorMsg;
		switch (zzipError)
		{
		case ZZIP_NO_ERROR:
			break;
		case ZZIP_OUTOFMEM:
			errorMsg = "Out of memory.";
			break;            
		case ZZIP_DIR_OPEN:
		case ZZIP_DIR_STAT: 
		case ZZIP_DIR_SEEK:
		case ZZIP_DIR_READ:
			errorMsg = "Unable to read zip file.";
			break;            
		case ZZIP_UNSUPP_COMPR:
			errorMsg = "Unsupported compression format.";
			break;            
		case ZZIP_CORRUPTED:
			errorMsg = "Corrupted archive.";
			break;            
		default:
			errorMsg = "Unknown error.";
			break;            
		};

		return errorMsg;
	}

	BOOL CPackZip::Create(const char* packName)
	{
		zzip_error_t zzipError;
		_zzipDir = zzip_dir_open(packName, &zzipError);
		if (zzipError != ZZIP_NO_ERROR)
		{
			GetEngine()->GetLog()->Write(MKLT_ERROR, "Create pack failed[%s]", __GetErrorDescription(zzipError).c_str());
			return FALSE;
		}

		return TRUE;
	}

	BOOL CPackZip::Destroy()
	{
		if (_zzipDir)
		{
			zzip_dir_close(_zzipDir);
			_zzipDir = 0;
		}

		return TRUE;
	}

	BOOL CPackZip::__Exist(const char* fileName, ZZIP_STAT* state)
	{
		return zzip_dir_stat(_zzipDir, fileName, state, ZZIP_CASEINSENSITIVE) == ZZIP_NO_ERROR ? TRUE : FALSE;
	}

	BOOL CPackZip::ReadFile(const char* fileName, CMemoryBlock* block)
	{
		ZZIP_STAT state;
		if (!__Exist(fileName, &state))
			return FALSE;

		ZZIP_FILE* zzipFile = zzip_file_open(_zzipDir, fileName, ZZIP_ONLYZIP | ZZIP_CASELESS);
		if (!zzipFile)
		{
			zzip_error_t zerr = (zzip_error_t)zzip_error(_zzipDir);
			GetEngine()->GetLog()->Write(MKLT_ERROR, "Read file failed[%s]", __GetErrorDescription(zerr).c_str());

			return FALSE;
		}

		if (!block->Alloc(state.st_size))
			return FALSE;

		zzip_ssize_t rsize = zzip_file_read(zzipFile, (void*)block->GetBuffer(), state.st_size);
		if (rsize != state.st_size)
			return FALSE;

		zzip_file_close(zzipFile);

		return TRUE;
	}
}